package com.zlp.mall.search.service.impl;

import com.zlp.mall.search.domain.EsProduct;
import com.zlp.mall.search.domain.EsSpu;
import com.zlp.mall.search.domain.Googs3;
import com.zlp.mall.search.repository.EsSpuRepository;
import com.zlp.mall.search.repository.GoodsRepository;
import com.zlp.mall.search.service.EsGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 搜索商品管理Service实现类
 * @since 2021-11-3 10:46:46
 */
@Service
@Slf4j(topic = "EsGoodsService")
public class EsGoodsServiceImpl implements EsGoodsService {

    private static final Logger LOGGER = LoggerFactory.getLogger(EsGoodsServiceImpl.class);



    @Autowired
    private GoodsRepository goodsRepository;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    private static final String PRE_TAG = "<font color='red'>";//google的色值
    private static final String POST_TAG = "</font>";

    @Override
    public int importAll(Integer id) {

        List<Googs3> list = new ArrayList<>();
        list.add(new Googs3(1L,"充电权益2.0 3个月",28L,100L));
        list.add(new Googs3(2L,"充电权益2.0 12个月",35L,490L));
        Iterable<Googs3> iterator = goodsRepository.saveAll(list);
        return list.size();
    }


    @Override
    public Page<Googs3> search(String keyword, Integer pageNum, Integer pageSize, Integer sort) {


        Pageable pageable = PageRequest.of(pageNum, pageSize);
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //分页
        nativeSearchQueryBuilder.withPageable(pageable);
        //过滤
        if (StringUtils.isEmpty(keyword)) {
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.must(QueryBuilders.termQuery("name", keyword));
            nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
        }

        BoolQueryBuilder newNumberLte30 = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("newNumber").lte(30));
        BoolQueryBuilder newNumberGt30Lte60 = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("newNumber").gt(30).lte(60));
        BoolQueryBuilder newNumberGt60Lte90 = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("newNumber").gt(60).lte(90));
        BoolQueryBuilder newNumberGt90 = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("newNumber").gt(90));

        BoolQueryBuilder browseGt1000 = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("browse").gt(1000));
        BoolQueryBuilder browseGt500Lte1000 = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("browse").gt(500).lte(100));
        BoolQueryBuilder browseGt100Lte500 = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("browse").gt(100).lte(500));
        BoolQueryBuilder browseLt100 = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("browse").lt(100));

        List<FunctionScoreQueryBuilder.FilterFunctionBuilder> filterFunctionBuilders = new ArrayList<>();

        filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(newNumberLte30,ScoreFunctionBuilders.weightFactorFunction(1000)));
        filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(newNumberGt30Lte60,ScoreFunctionBuilders.weightFactorFunction(900)));
        filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(newNumberGt60Lte90,ScoreFunctionBuilders.weightFactorFunction(500)));
        filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(newNumberGt90,ScoreFunctionBuilders.weightFactorFunction(100)));
        filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(browseGt1000,ScoreFunctionBuilders.weightFactorFunction(800)));
        filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(browseGt500Lte1000,ScoreFunctionBuilders.weightFactorFunction(640)));
        filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(browseGt100Lte500,ScoreFunctionBuilders.weightFactorFunction(400)));
        filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(browseLt100,ScoreFunctionBuilders.weightFactorFunction(80)));

        FunctionScoreQueryBuilder.FilterFunctionBuilder[] builders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[filterFunctionBuilders.size()];
        filterFunctionBuilders.toArray(builders);
        // 权重
        FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(builders)
                .boostMode(CombineFunction.SUM).scoreMode(FunctionScoreQuery.ScoreMode.SUM);

        nativeSearchQueryBuilder.withQuery(functionScoreQueryBuilder);
        NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();

        LOGGER.info("DSL:{}", searchQuery.getQuery().toString());
        SearchHits<Googs3> searchHits = elasticsearchRestTemplate.search(searchQuery, Googs3.class);
        if (searchHits.getTotalHits() <= 0) {
            return new PageImpl<>(null, pageable, 0);
        }
        List<Googs3> searchProductList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
        return new PageImpl<>(searchProductList, pageable, searchHits.getTotalHits());

    }

}
